package com.google.code.opengw.server.initializer;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

import com.google.code.opengw.server.Constants;
import com.google.code.opengw.server.Server;
import com.google.code.opengw.server.support.XMLParser;
import com.google.code.opengw.support.OpenGWException;
import com.google.code.opengw.support.OpenGWLogger;

class ConfigInitializer {

	void initialize() throws ParserConfigurationException,
			OpenGWException, SAXException, IOException {
		Server server = Server.getInstance();

		DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
				.newInstance();
		DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();

		/*
		 * START OF config.xml PARSING
		 */
		File configFile = server.getConfigXML();
		if (!configFile.exists() || !configFile.isFile())
			throw new OpenGWException(OpenGWException.CONFIG_FILE_NOT_FOUND);

		Document doc = docBuilder.parse(configFile);
		doc.getDocumentElement().normalize();

		/*
		 * START OF CONFIG DEFAULT VALUES INITIALIZATION
		 */

		Node defaultValuesNode = XMLParser.getFirstNodeFromDoc(doc,
				Constants.CONFIG_FILE_DEFAULT_VALUES,
				Server.CONFIG_FILE_NAME, true);

		Node defaultValueElementNode = XMLParser.getFirstNodeFromElement(
				((Element) defaultValuesNode),
				Constants.CONFIG_FILE_DEFAULT_CONNECTION_QUEUE_SIZE,
				Server.CONFIG_FILE_NAME, true);
		server.setConnectionQueueSize(Integer
				.parseInt(defaultValueElementNode.getFirstChild()
						.getNodeValue()));
		OpenGWLogger.addInfo(this.getClass(), "Connection queue size initialized : " + server.getConnectionQueueSize());

		defaultValueElementNode = XMLParser.getFirstNodeFromElement(
				((Element) defaultValuesNode),
				Constants.CONFIG_FILE_DEFAULT_INITIAL_WORKER_COUNT,
				Server.CONFIG_FILE_NAME, true);
		server.setInitialWorkerCount(Integer
				.parseInt(defaultValueElementNode.getFirstChild()
						.getNodeValue()));
		OpenGWLogger.addInfo(this.getClass(), "Initial worker count initialized : " + server.getInitialWorkerCount());

		defaultValueElementNode = XMLParser.getFirstNodeFromElement(
				((Element) defaultValuesNode),
				Constants.CONFIG_FILE_DEFAULT_WORKER_INCREASEMENT_COUNT,
				Server.CONFIG_FILE_NAME, true);
		server.setWorkerIncreasementCount(Integer
				.parseInt(defaultValueElementNode.getFirstChild()
						.getNodeValue()));
		OpenGWLogger.addInfo(this.getClass(), "Worker increasement count initialized : " + server.getWorkerIncreasementCount());

		defaultValueElementNode = XMLParser.getFirstNodeFromElement(
				((Element) defaultValuesNode),
				Constants.CONFIG_FILE_DEFAULT_MAX_WORKER_COUNT,
				Server.CONFIG_FILE_NAME, true);
		server.setMaxWorkerCount(Integer
				.parseInt(defaultValueElementNode.getFirstChild()
						.getNodeValue()));
		OpenGWLogger.addInfo(this.getClass(), "MAX worker count initialized : " + server.getMaxWorkerCount());

		defaultValueElementNode = XMLParser.getFirstNodeFromElement(
				((Element) defaultValuesNode),
				Constants.CONFIG_FILE_DEFAULT_CONNECTION_TIMEOUT,
				Server.CONFIG_FILE_NAME, true);
		server.setConnectionTimeout(Integer
				.parseInt(defaultValueElementNode.getFirstChild()
						.getNodeValue()));
		OpenGWLogger.addInfo(this.getClass(), "Connection timeout initialized : " + server.getConnectionTimeout());

		defaultValueElementNode = XMLParser.getFirstNodeFromElement(
				((Element) defaultValuesNode),
				Constants.CONFIG_FILE_DEFAULT_IDLE_TIMEOUT,
				Server.CONFIG_FILE_NAME, true);
		server.setConnectionIdleTimeout(Integer
				.parseInt(defaultValueElementNode.getFirstChild()
						.getNodeValue()));
		OpenGWLogger.addInfo(this.getClass(), "Idle timeout initialized : " + server.getConnectionIdleTimeout());

		defaultValueElementNode = XMLParser.getFirstNodeFromElement(
				((Element) defaultValuesNode),
				Constants.CONFIG_FILE_DEFAULT_ALLOW_PARAMETERS,
				Server.CONFIG_FILE_NAME, true);
		server.setAllowParameters(defaultValueElementNode
				.getFirstChild().getNodeValue().equalsIgnoreCase("YES") ? true
				: false);
		OpenGWLogger.addInfo(this.getClass(), "Allow Parameters initialized : " + server.isAllowParameters());

		defaultValueElementNode = XMLParser.getFirstNodeFromElement(
				((Element) defaultValuesNode),
				Constants.CONFIG_FILE_DEFAULT_AVAILABLE_METHODS,
				Server.CONFIG_FILE_NAME, true);
		server.setAvailableMethods(defaultValueElementNode
				.getFirstChild().getNodeValue());
		OpenGWLogger.addInfo(this.getClass(), "Avaliable HTTP methods initialized : " + server.getAvailableMethods());

		defaultValueElementNode = XMLParser.getFirstNodeFromElement(
				((Element) defaultValuesNode),
				Constants.CONFIG_FILE_DEFAULT_ALLOW_PATH_EXTENSION,
				Server.CONFIG_FILE_NAME, true);
		server.setAllowPathExtension(defaultValueElementNode
				.getFirstChild().getNodeValue().equalsIgnoreCase("YES") ? true
				: false);
		OpenGWLogger.addInfo(this.getClass(), "Default Path Extension available initialized : " + server.isAllowPathExtension());
		
		defaultValueElementNode = XMLParser.getFirstNodeFromElement(
				((Element) defaultValuesNode),
				Constants.CONFIG_FILE_DEFAULT_CONNECTION_BUFFER_SIZE,
				Server.CONFIG_FILE_NAME, true);
		server.setConnectionBufferSize(Integer
				.parseInt(defaultValueElementNode.getFirstChild()
						.getNodeValue()));
		OpenGWLogger.addInfo(this.getClass(), "Connection buffer size initialized : " + server.getConnectionBufferSize());
		
		defaultValueElementNode = XMLParser.getFirstNodeFromElement(
				((Element) defaultValuesNode),
				Constants.CONFIG_FILE_DEFAULT_READ_BUFFER_SIZE,
				Server.CONFIG_FILE_NAME, true);
		server.setReadBufferSize(Integer
				.parseInt(defaultValueElementNode.getFirstChild()
						.getNodeValue()));
		OpenGWLogger.addInfo(this.getClass(), "Read buffer size initialized : " + server.getReadBufferSize());
		
		defaultValueElementNode = XMLParser.getFirstNodeFromElement(
				((Element) defaultValuesNode),
				Constants.CONFIG_FILE_DEFAULT_READ_TIMEOUT,
				Server.CONFIG_FILE_NAME, true);
		server.setReadTimeout(Integer
				.parseInt(defaultValueElementNode.getFirstChild()
						.getNodeValue()));
		OpenGWLogger.addInfo(this.getClass(), "Read timeout initialized : " + server.getReadTimeout());
		
		defaultValueElementNode = XMLParser.getFirstNodeFromElement(
				((Element) defaultValuesNode),
				Constants.CONFIG_FILE_DEFAULT_DEPLOYMENT_CONTROL_INTERVAL,
				Server.CONFIG_FILE_NAME, true);
		server.setDeploymentControlInterval(Integer
				.parseInt(defaultValueElementNode.getFirstChild()
						.getNodeValue()));
		OpenGWLogger.addInfo(this.getClass(), "Deployment control interval initialized : " + server.getDeploymentControlInterval());

		/*
		 * END OF CONFIG DEFAULT VALUES INITIALIZATION
		 */
		

		/*
		 * START OF KEYSTORE PASSWORD READING
		 */

		Node keyStoreNode = XMLParser.getFirstNodeFromDoc(doc,
				Constants.CONFIG_FILE_KEYSTORE_PASSWORD,
				Server.CONFIG_FILE_NAME, true);
		server.setKeystorePassword(keyStoreNode.getFirstChild().getNodeValue());
		OpenGWLogger.addInfo(this.getClass(), "Keystore password initialized : " );

		/*
		 * END OF KEYSTORE PASSWORD READING
		 */
		
		/*
		 * START OF DOMAINS INITIALIZATION
		 */
		OpenGWLogger.addInfo(SystemInitializer.class, "Domain initialization starts");
		DomainInitializer domainInitializer = new DomainInitializer();
		domainInitializer.initialize(doc);
		OpenGWLogger.addInfo(SystemInitializer.class, "Domain initialization successfullly finished");
		
		/*
		 * END OF DOMAINS INITIALIZATION
		 */

		/*
		 * END OF config.xml PARSING
		 */
	}
}
